/**
 * WebRTC客户端
 * 用于通过WebRTC从设备服务器获取视频流和UI控件树
 * 
 * 注意：此类依赖于全局的 deviceSocket 实例（来自 socketio-client.js）
 * 复用已有的WebSocket连接，避免重复实现连接逻辑
 */

class WebRTCClient {
    /**
     * 创建WebRTC客户端实例
     * @param {Object} options - 配置选项
     * @param {string} options.deviceSn - 设备序列号
     * @param {string} options.host - 主机地址
     * @param {number} options.port - 端口号
     * @param {Function} options.onVideoFrame - 视频帧回调函数
     * @param {Function} options.onUiTree - UI树回调函数
     * @param {Function} options.onConnected - 连接成功回调函数
     * @param {Function} options.onDisconnected - 断开连接回调函数
     * @param {Function} options.onError - 错误回调函数
     */
    constructor(options) {
        this.deviceSn = options.deviceSn;
        this.host = options.host || window.location.hostname;
        this.port = options.port || (window.location.protocol === 'https:' ? 443 : 80);
        this.onVideoFrame = options.onVideoFrame || function() {};
        this.onUiTree = options.onUiTree || function() {};
        this.onPerformance = options.onPerformance || function() {};
        this.onConnected = options.onConnected || function() {};
        this.onDisconnected = options.onDisconnected || function() {};
        this.onError = options.onError || function() {};
        
        this.peerConnection = null;
        this.dataChannel = null;
        this.uiDataChannel = null;
        this.inputDataChannel = null;
        this.performanceDataChannel = null;
        this.videoElement = null;
        this.clientId = null;
        this.connected = false;
        this.reconnectAttempts = 0;
        this.maxReconnectAttempts = 5;
        this.reconnectTimer = null;
        this.reconnectInterval = 5000; // 5秒重连间隔
        
        // 初始化socket为null，在_initWebSocket中设置
        this.socket = null;
        this.pendingRequests = new Map();
        this.requestId = 0;
        this.webrtcResponseHandler = null;
        
        // ICE服务器配置
        this.iceServers = [
            { urls: 'stun:stun.l.google.com:19302' },
            { urls: 'stun:stun1.l.google.com:19302' },
            { urls: 'stun:stun2.l.google.com:19302' },
            { urls: 'stun:stun3.l.google.com:19302' },
            { urls: 'stun:stun4.l.google.com:19302' }
        ];
    }
    
    /**
     * 检查WebRTC连接是否已建立
     * @returns {boolean} 连接状态
     */
    isConnected() {
        return this.connected && this.peerConnection !== null;
    }
    
    /**
     * 请求UI树数据
     * @returns {Promise<void>}
     */
    requestUiTree() {
        return new Promise((resolve, reject) => {
            if (!this.isConnected() || !this.inputDataChannel) {
                reject(new Error('WebRTC连接未建立或输入数据通道不可用'));
                return;
            }
            
            if (this.inputDataChannel.readyState === 'open') {
                try {
                    this.inputDataChannel.send(JSON.stringify({
                        type: 'control',
                        command: 'request_uitree',
                        deviceSn: this.deviceSn
                    }));
                    resolve();
                } catch (error) {
                    console.error('发送UI树请求失败:', error);
                    reject(error);
                }
            } else {
                reject(new Error('输入数据通道未打开'));
            }
        });
    }
    
    /**
     * 请求性能数据
     * @returns {Promise<void>}
     */
    requestPerformanceData() {
        return new Promise((resolve, reject) => {
            if (!this.isConnected() || !this.inputDataChannel) {
                reject(new Error('WebRTC连接未建立或输入数据通道不可用'));
                return;
            }
            
            if (this.inputDataChannel.readyState === 'open') {
                try {
                    this.inputDataChannel.send(JSON.stringify({
                        type: 'control',
                        command: 'request_performance',
                        deviceSn: this.deviceSn
                    }));
                    resolve();
                } catch (error) {
                    console.error('发送性能数据请求失败:', error);
                    reject(error);
                }
            } else {
                reject(new Error('输入数据通道未打开'));
            }
        });
    }
    
    /**
     * 初始化WebSocket连接
     * @private
     * @returns {Promise<void>}
     */
    _initWebSocket() {
        return new Promise((resolve, reject) => {
            // 检查全局deviceSocket是否存在
            if (typeof deviceSocket === 'undefined') {
                reject(new Error('deviceSocket未定义，请确保已加载socketio-client.js'));
                return;
            }
            
            // 使用全局deviceSocket实例
            this.socket = deviceSocket;
            
            // 检查deviceSocket是否已连接
            if (this.socket.connected) {
                this._setupWebRTCHandlers();
                resolve();
                return;
            }
            
            // 如果未连接，先连接deviceSocket
            const connectHandler = () => {
                console.log('WebSocket连接已建立');
                this._setupWebRTCHandlers();
                this.socket.off('connect', connectHandler);
                this.socket.off('error', errorHandler);
                resolve();
            };
            
            const errorHandler = (error) => {
                console.error('WebSocket连接错误:', error);
                this.socket.off('connect', connectHandler);
                this.socket.off('error', errorHandler);
                reject(error);
            };
            
            this.socket.on('connect', connectHandler);
            this.socket.on('error', errorHandler);
            
            // 如果deviceSocket未连接，则连接它
            if (!this.socket.connected) {
                this.socket.connect();
            }
        });
    }
    
    /**
     * 设置WebRTC相关的事件处理器
     * @private
     */
    _setupWebRTCHandlers() {
        // 监听WebRTC注册响应
        this.socket.socket.on('webrtc_registered', (data) => {
            console.log('WebRTC注册成功:', data);
            this.clientId = data.client_id;
        });
        
        // 监听设备连接响应
        this.socket.socket.on('webrtc_connected', (data) => {
            console.log('WebRTC连接成功:', data);
            if (this.pendingRequests.has('connect')) {
                const { resolve } = this.pendingRequests.get('connect');
                this.pendingRequests.delete('connect');
                resolve({ status: data.status });
            }
        });
        
        // 监听WebRTC offer响应
        this.socket.socket.on('webrtc_offer_response', (data) => {
            console.log('WebRTC请求offer响应:', data);
            if (this.pendingRequests.has('request_offer')) {
                const { resolve, reject } = this.pendingRequests.get('request_offer');
                this.pendingRequests.delete('request_offer');
                if (data.status === 'ok' && data.offer) {
                    resolve(data.offer);
                } else {
                    reject(new Error(data.message || '请求offer失败'));
                }
            }
        });
        
        // 监听answer处理完成
        this.socket.socket.on('webrtc_answer_sent', (data) => {
            console.log('WebRTC发送answer成功:', data);
            if (this.pendingRequests.has('send_answer')) {
                const { resolve } = this.pendingRequests.get('send_answer');
                this.pendingRequests.delete('send_answer');
                resolve({ status: data.status });
            }
        });
        
        // 监听ICE候选处理响应（简化版）
        this.socket.socket.on('webrtc_ice_candidate_sent', (data) => {
            console.log('WebRTC ICE候选处理响应:', data);
            // 在aiortc中，ICE候选已自动包含在SDP中，无需额外处理
            if (data.message) {
                console.log('ICE候选处理:', data.message);
            }
        });
        
        // 监听断开连接响应
        this.socket.socket.on('webrtc_disconnected', (data) => {
            console.log('WebRTC断开连接成功:', data);
            if (this.pendingRequests.has('disconnect')) {
                const { resolve } = this.pendingRequests.get('disconnect');
                this.pendingRequests.delete('disconnect');
                resolve({ status: data.status });
            }
        });
        
        // 监听WebRTC错误
        this.socket.socket.on('webrtc_error', (data) => {
            console.error('WebRTC错误:', data);
            // 拒绝所有待处理的请求
            this.pendingRequests.forEach(({ reject }) => {
                reject(new Error(data.message || 'WebRTC错误'));
            });
            this.pendingRequests.clear();
            
            // 设置连接状态为失败
            this.connected = false;
            
            // 触发错误回调
            this.onError(data.message || 'WebRTC错误');
            
            // 尝试重连
            this._attemptReconnect();
        });
        
        // 监听断开连接事件
        this.socket.on('disconnect', () => {
            console.log('WebSocket连接已断开');
            // 清理待处理的请求
            this.pendingRequests.forEach(({ reject }) => {
                reject(new Error('WebSocket连接断开'));
            });
            this.pendingRequests.clear();
        });
    }
    
    /**
     * 通过WebSocket发送请求
     * @private
     * @param {string} action - 操作类型
     * @param {Object} data - 请求数据
     * @returns {Promise<Object>} 响应结果
     */
    _sendWebSocketRequest(action, data) {
        return new Promise((resolve, reject) => {
            // 检查socket是否可用
            if (!this.socket || !this.socket.socket) {
                reject(new Error('WebSocket连接不可用'));
                return;
            }
            
            if (!this.socket.connected) {
                reject(new Error('WebSocket未连接'));
                return;
            }
            
            // 存储请求处理器
            this.pendingRequests.set(action, { resolve, reject });
            
            // 根据action类型发送不同的事件
            if (action === 'connect') {
                this.socket.socket.emit('webrtc_connect', {
                    client_id: this.clientId,
                    device_sn: data.device_sn
                });
            } else if (action === 'request_offer') {
                this.socket.socket.emit('webrtc_request_offer', {
                    client_id: this.clientId
                });
            } else if (action === 'send_answer') {
                this.socket.socket.emit('webrtc_send_answer', {
                    client_id: this.clientId,
                    answer: data.answer
                });
            } else if (action === 'ice_candidate') {
                this.socket.socket.emit('webrtc_send_ice_candidate', {
                    client_id: this.clientId,
                    candidate: data.candidate
                });
                // 在aiortc中，ICE候选已自动包含在SDP中，这里发送主要为了兼容性
                // 服务端会简化处理，直接返回成功响应
                resolve({ status: 'ok' });
                return;
            } else if (action === 'disconnect') {
                this.socket.socket.emit('webrtc_disconnect', {
                    client_id: this.clientId
                });
            } else {
                reject(new Error(`未知的操作类型: ${action}`));
                return;
            }
            
            // 设置超时
            setTimeout(() => {
                if (this.pendingRequests.has(action)) {
                    this.pendingRequests.delete(action);
                    reject(new Error('请求超时'));
                }
            }, 10000); // 10秒超时
        });
    }
    
    /**
     * 连接到设备服务器
     * @param {HTMLVideoElement} videoElement - 视频元素
     * @returns {Promise} 连接结果
     */
    async connect(videoElement) {
        try {
            this.videoElement = videoElement;
            
            // 初始化WebSocket连接
            await this._initWebSocket();
            
            // 注册WebRTC客户端
            await this._registerClient();
            
            // 连接设备
            const connectResponse = await this._connectDevice();
            if (connectResponse.status !== 'ok') {
                throw new Error(connectResponse.message || '连接设备失败');
            }

            // 请求服务端创建offer
            const offer = await this._requestOffer();

            // 创建RTCPeerConnection
            this._initPeerConnection();
            
            // 设置远程offer
            await this.peerConnection.setRemoteDescription(new RTCSessionDescription(offer));
            
            // 创建并发送answer
            const answer = await this.peerConnection.createAnswer();
            await this.peerConnection.setLocalDescription(answer);
            
            const answerResponse = await this._sendAnswer(answer);
            if (answerResponse.status !== 'ok') {
                throw new Error(answerResponse.message || '发送answer失败');
            }
            
            // 设置连接状态
            this.connected = true;
            
            return { status: 'ok' };
        } catch (error) {
            console.error('WebRTC连接失败:', error);
            this.connected = false;
            this.onError(error.message || '连接失败');
            return { status: 'err', message: error.message || '连接失败' };
        }
    }
    
    /**
     * 断开连接
     * @returns {Promise} 断开连接结果
     */
    async disconnect() {
        try {
            // 通知服务器断开连接
            if (this.socket && this.socket.connected) {
                await this._disconnectFromServer();
            }
            
            // 清理所有资源
            this._cleanup();
            
            // 重置重连次数
            this.reconnectAttempts = 0;
            
            return { status: 'ok' };
        } catch (error) {
            console.error('断开连接失败:', error);
            // 即使通知服务器失败，也要清理本地资源
            this._cleanup();
            this.reconnectAttempts = 0;
            return { status: 'err', message: error.message || '断开连接失败' };
        }
    }
    
    /**
     * 注册WebRTC客户端
     * @private
     * @returns {Promise} 注册结果
     */
    async _registerClient() {
        // 生成客户端ID
        if (!this.clientId) {
            this.clientId = 'client_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
        }
        
        // 检查socket是否可用
        if (!this.socket || !this.socket.socket) {
            throw new Error('WebSocket连接不可用');
        }
        
        this.socket.socket.emit('webrtc_register', {
            client_id: this.clientId
        });
        
        // 等待注册完成
        return new Promise((resolve, reject) => {
            const handler = (data) => {
                if (data.client_id === this.clientId) {
                    this.socket.socket.off('webrtc_registered', handler);
                    resolve({ status: 'ok' });
                }
            };
            
            // 设置超时
            const timeout = setTimeout(() => {
                this.socket.socket.off('webrtc_registered', handler);
                reject(new Error('注册客户端超时'));
            }, 5000);
            
            this.socket.socket.on('webrtc_registered', (data) => {
                if (data.client_id === this.clientId) {
                    clearTimeout(timeout);
                    handler(data);
                }
            });
        });
    }
    
    /**
     * 连接设备
     * @private
     * @returns {Promise} 连接结果
     */
    async _connectDevice() {
        return await this._sendWebSocketRequest('connect', {
            device_sn: this.deviceSn
        });
    }
    
    /**
     * 初始化PeerConnection
     * @private
     */
    _initPeerConnection() {
        // 创建RTCPeerConnection实例
        this.peerConnection = new RTCPeerConnection({
            iceServers: this.iceServers
        });
        
        // 处理ICE候选（简化版）
        this.peerConnection.onicecandidate = async (event) => {
            if (event.candidate) {
                try {
                    // 在aiortc中，ICE候选已自动包含在SDP中
                    // 这里仍然发送以保持兼容性，但服务端会简化处理
                    await this._sendWebSocketRequest('ice_candidate', {
                        candidate: event.candidate
                    });
                } catch (error) {
                    console.error('发送ICE候选失败:', error);
                }
            } else {
                console.log('ICE候选收集完成');
            }
        };
        
        // 处理ICE连接状态变化
        this.peerConnection.oniceconnectionstatechange = () => {
            const state = this.peerConnection.iceConnectionState;
            console.log('ICE连接状态:', state);
            
            if (state === 'connected' || state === 'completed') {
                // ICE连接成功
                this.connected = true;
                this.reconnectAttempts = 0;
                this.onConnected();
            } else if (state === 'failed' || state === 'disconnected' || state === 'closed') {
                // ICE连接失败或断开
                this.connected = false;
                
                // 尝试重连
                this._attemptReconnect();
            }
        };
        
        // 处理连接状态变化
        this.peerConnection.onconnectionstatechange = () => {
            const state = this.peerConnection.connectionState;
            console.log('连接状态:', state);
            
            if (state === 'connected') {
                this.connected = true;
                this.reconnectAttempts = 0;
            } else if (state === 'disconnected' || state === 'failed' || state === 'closed') {
                this.connected = false;
                
                if (state === 'disconnected' || state === 'failed') {
                    // 尝试重连
                    this._attemptReconnect();
                }
            }
        };
        
        // 处理媒体轨道接收
        this.peerConnection.ontrack = (event) => {
            if (event.track.kind === 'video') {
                // 接收到视频轨道
                if (this.videoElement) {
                    if (!this.videoElement.srcObject) {
                        this.videoElement.srcObject = new MediaStream();
                    }
                    
                    // 添加视频轨道到媒体流
                    this.videoElement.srcObject.addTrack(event.track);
                    
                    // 触发视频帧回调
                    this.onVideoFrame();
                }
            }
        };
        
        // 处理数据通道接收
        this.peerConnection.ondatachannel = (event) => {
            if (event.channel.label === 'ui_tree') {
                // 接收到UI控件树数据通道
                this._setupUiDataChannel(event.channel);
            } else if (event.channel.label === 'input') {
                // 接收到输入数据通道
                this._setupInputDataChannel(event.channel);
            } else if (event.channel.label === 'performance') {
                // 接收到性能数据通道
                this._setupPerformanceDataChannel(event.channel);
            } else if (event.channel.label === 'control') {
                // 接收到控制数据通道
                this._setupControlDataChannel(event.channel);
            }
        };
    }
    
    /**
     * 请求服务端创建offer
     * @private
     * @returns {Promise} offer结果
     */
    async _requestOffer() {
        try {
            return await this._sendWebSocketRequest('request_offer', {});
        } catch (error) {
            console.error('请求offer失败:', error);
            throw error;
        }
    }
    
    /**
     * 发送answer到服务端
     * @private
     * @param {RTCSessionDescription} answer - 本地answer
     * @returns {Promise} 处理结果
     */
    async _sendAnswer(answer) {
        return await this._sendWebSocketRequest('send_answer', {
            answer: answer
        });
    }
    

    
    /**
     * 通知服务器断开连接
     * @private
     * @returns {Promise} 处理结果
     */
    async _disconnectFromServer() {
        return await this._sendWebSocketRequest('disconnect', {});
    }
    

    
    /**
     * 设置UI数据通道
     * @private
     * @param {RTCDataChannel} channel - UI数据通道对象
     */
    _setupUiDataChannel(channel) {
        this.uiDataChannel = channel;
        if (!this.uiDataChannel) return;
        
        this.uiDataChannel.onopen = () => {
            console.log('UI数据通道已打开');
        };
        
        this.uiDataChannel.onclose = () => {
            console.log('UI数据通道已关闭');
        };
        
        this.uiDataChannel.onerror = (error) => {
            console.error('UI数据通道错误:', error);
            this.onError('UI数据通道错误: ' + error.message);
        };
        
        this.uiDataChannel.onmessage = (event) => {
            try {
                const data = JSON.parse(event.data);
                // 接收到UI控件树数据
                this.onUiTree(data);
            } catch (error) {
                console.error('解析UI数据通道消息失败:', error);
            }
        };
    }
    
    /**
     * 设置输入数据通道
     * @private
     * @param {RTCDataChannel} channel - 输入数据通道对象
     */
    _setupInputDataChannel(channel) {
        this.inputDataChannel = channel;
        if (!this.inputDataChannel) return;
        
        this.inputDataChannel.onopen = () => {
            console.log('输入数据通道已打开');
            // 数据通道打开后立即请求UI树数据
            this.requestUiTree().catch(error => {
                console.error('初始UI树请求失败:', error);
            });
        };
        
        this.inputDataChannel.onclose = () => {
            console.log('输入数据通道已关闭');
        };
        
        this.inputDataChannel.onerror = (error) => {
            console.error('输入数据通道错误:', error);
            this.onError('输入数据通道错误: ' + error.message);
        };
    }
    
    /**
     * 设置性能数据通道
     * @private
     * @param {RTCDataChannel} channel - 性能数据通道对象
     */
    _setupPerformanceDataChannel(channel) {
        this.performanceDataChannel = channel;
        if (!this.performanceDataChannel) return;
        
        this.performanceDataChannel.onopen = () => {
            console.log('性能数据通道已打开');
        };
        
        this.performanceDataChannel.onclose = () => {
            console.log('性能数据通道已关闭');
        };
        
        this.performanceDataChannel.onerror = (error) => {
            console.error('性能数据通道错误:', error);
            this.onError('性能数据通道错误: ' + error.message);
        };
        
        this.performanceDataChannel.onmessage = (event) => {
            try {
                const data = JSON.parse(event.data);
                // 接收到性能数据
                this.onPerformance(data);
            } catch (error) {
                console.error('解析性能数据通道消息失败:', error);
            }
        };
    }
    
    /**
     * 设置控制数据通道
     * @private
     * @param {RTCDataChannel} channel - 控制数据通道对象
     */
    _setupControlDataChannel(channel) {
        this.controlDataChannel = channel;
        if (!this.controlDataChannel) return;
        
        this.controlDataChannel.onopen = () => {
            console.log('控制数据通道已打开');
        };
        
        this.controlDataChannel.onclose = () => {
            console.log('控制数据通道已关闭');
        };
        
        this.controlDataChannel.onerror = (error) => {
            console.error('控制数据通道错误:', error);
            this.onError('控制数据通道错误: ' + error.message);
        };
        
        this.controlDataChannel.onmessage = (event) => {
            try {
                const data = JSON.parse(event.data);
                
                // 处理不同类型的控制消息
                if (data.type === 'connection_success') {
                    // 接收到连接成功验证消息
                    console.log('🎉 WebRTC P2P连接验证成功:', data.message);
                    console.log('连接建立时间戳:', new Date(data.timestamp * 1000).toLocaleString());
                    
                    // 可以在这里触发其他连接成功的处理逻辑
                    this.onConnectionVerified && this.onConnectionVerified(data);
                } else {
                    // 其他控制消息
                    console.log('收到控制消息:', data);
                }
            } catch (error) {
                console.error('解析控制数据通道消息失败:', error);
            }
        };
    }
    
    /**
     * 发送鼠标点击事件
     * @param {number} x - 相对X坐标 (0-1)
     * @param {number} y - 相对Y坐标 (0-1)
     * @param {string} button - 鼠标按钮 ('left', 'right', 'middle')
     * @returns {Promise<void>}
     */
    sendMouseClick(x, y, button = 'left') {
        return new Promise((resolve, reject) => {
            if (!this.isConnected() || !this.inputDataChannel) {
                reject(new Error('WebRTC连接未建立或输入数据通道不可用'));
                return;
            }
            
            if (this.inputDataChannel.readyState === 'open') {
                try {
                    this.inputDataChannel.send(JSON.stringify({
                        type: 'mouse',
                        action: 'click',
                        x: x,
                        y: y,
                        button: button
                    }));
                    resolve();
                } catch (error) {
                    console.error('发送鼠标点击失败:', error);
                    reject(error);
                }
            } else {
                reject(new Error('输入数据通道未打开'));
            }
        });
    }
    
    /**
     * 尝试重连
     * @private
     */
    _attemptReconnect() {
        // 如果已经在重连过程中，不要重复启动
        if (this.reconnectTimer) {
            return;
        }
        
        if (this.reconnectAttempts >= this.maxReconnectAttempts) {
            console.error('达到最大重连次数，停止重连');
            this.onError('连接失败，已达到最大重连次数');
            return;
        }
        
        this.reconnectAttempts++;
        const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts - 1), 30000); // 指数退避，最大30秒
        
        console.log(`第 ${this.reconnectAttempts} 次重连尝试，${delay}ms 后开始...`);
        
        this.reconnectTimer = setTimeout(async () => {
            this.reconnectTimer = null;
            try {
                console.log('开始重连...');
                // 先清理当前连接
                this._cleanup();
                // 重新连接
                await this.connect(this.videoElement);
                console.log('重连成功');
            } catch (error) {
                console.error('重连失败:', error);
                this._attemptReconnect(); // 继续尝试重连
            }
        }, delay);
    }
    
    /**
     * 清理连接资源
     * @private
     */
    _cleanup() {
        // 清理重连定时器
        if (this.reconnectTimer) {
            clearTimeout(this.reconnectTimer);
            this.reconnectTimer = null;
        }
        
        // 关闭数据通道
        if (this.uiDataChannel) {
            this.uiDataChannel.close();
            this.uiDataChannel = null;
        }
        
        if (this.inputDataChannel) {
            this.inputDataChannel.close();
            this.inputDataChannel = null;
        }
        
        if (this.performanceDataChannel) {
            this.performanceDataChannel.close();
            this.performanceDataChannel = null;
        }
        
        if (this.controlDataChannel) {
            this.controlDataChannel.close();
            this.controlDataChannel = null;
        }
        
        // 关闭对等连接
        if (this.peerConnection) {
            this.peerConnection.close();
            this.peerConnection = null;
        }
        
        // 清理待处理的请求
        this.pendingRequests.clear();
        
        // 重置连接状态
        this.connected = false;
    }
}